/*****************************************************************
*  Copyright (C) 2012  Marco Bavagnoli - lil.deimos@gmail.com    *
******************************************************************/

#ifndef HORIZON_H
#define HORIZON_H

#include <QDeclarativeItem>
//#include <QRotationSensor>
//#include <QRotationReading>
#include <QAccelerometer>
#include <QAccelerometerReading>
#include <QPainter>
#include <QPen>

QTM_USE_NAMESPACE

#define ROT_SAMPLES 5

class Horizon : public QDeclarativeItem
{
    Q_OBJECT
    Q_PROPERTY(QColor color         READ color WRITE setColor NOTIFY colorChanged)
    Q_PROPERTY(int    penWidth      READ penWidth WRITE setPenWidth NOTIFY penWidthChanged)
    Q_PROPERTY(bool   active        READ active WRITE setActive NOTIFY activeChanged)
    Q_PROPERTY(qreal  averageRotX   READ averageRotX NOTIFY averageRotXChanged)
    Q_PROPERTY(qreal  averageRotY   READ averageRotY NOTIFY averageRotYChanged)
    Q_PROPERTY(qreal  averageRotZ   READ averageRotZ NOTIFY averageRotZChanged)
    Q_PROPERTY(qreal  calibrateMinX READ calibrateMinX WRITE setCalibrateMinX NOTIFY calibrateMinXChanged)
    Q_PROPERTY(qreal  calibrateMinY READ calibrateMinY WRITE setCalibrateMinY NOTIFY calibrateMinYChanged)
    Q_PROPERTY(qreal  calibrateMinZ READ calibrateMinZ WRITE setCalibrateMinZ NOTIFY calibrateMinZChanged)
    Q_PROPERTY(qreal  calibrateMaxX READ calibrateMaxX WRITE setCalibrateMaxX NOTIFY calibrateMaxXChanged)
    Q_PROPERTY(qreal  calibrateMaxY READ calibrateMaxY WRITE setCalibrateMaxY NOTIFY calibrateMaxYChanged)
    Q_PROPERTY(qreal  calibrateMaxZ READ calibrateMaxZ WRITE setCalibrateMaxZ NOTIFY calibrateMaxZChanged)

public:
    typedef struct listRot_ {
        qreal value;
        struct listRot_ *prev,*next;
    } listRot;

    explicit Horizon(QDeclarativeItem *parent = 0);
    ~Horizon();

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    ////////////////////////////////////////////////////
    /// Get methods
    QColor color()  { return m_color; }
    int penWidth()  { return m_penWidth; }
    bool active()   { return m_active; }
    qreal averageRotX() { return m_average_rotX; }
    qreal averageRotY() { return m_average_rotY; }
    qreal averageRotZ() { return m_average_rotZ; }
    qreal calibrateMinX() { return m_calibrateMinX; }
    qreal calibrateMinY() { return m_calibrateMinY; }
    qreal calibrateMinZ() { return m_calibrateMinZ; }
    qreal calibrateMaxX() { return m_calibrateMaxX; }
    qreal calibrateMaxY() { return m_calibrateMaxY; }
    qreal calibrateMaxZ() { return m_calibrateMaxZ; }

    ////////////////////////////////////////////////////
    /// Set methods
    void setColor(QColor &color);
    void setPenWidth(int newWidth);
    void setActive(bool b);
    void setCalibrateMinX(qreal value) { m_calibrateMinX = value; }
    void setCalibrateMinY(qreal value) { m_calibrateMinY = value; }
    void setCalibrateMinZ(qreal value) { m_calibrateMinZ = value; }
    void setCalibrateMaxX(qreal value) { m_calibrateMaxX = value; }
    void setCalibrateMaxY(qreal value) { m_calibrateMaxY = value; }
    void setCalibrateMaxZ(qreal value) { m_calibrateMaxZ = value; }

signals:
    ////////////////////////////////////////////////////
    /// Property signals
    void colorChanged();
    void penWidthChanged();
    void activeChanged();
    void averageRotXChanged();
    void averageRotYChanged();
    void averageRotZChanged();
    void calibrateMinXChanged();
    void calibrateMinYChanged();
    void calibrateMinZChanged();
    void calibrateMaxXChanged();
    void calibrateMaxYChanged();
    void calibrateMaxZChanged();

protected:
    QAccelerometer *m_rotation;
    QAccelerometerReading *m_reading;
    qreal m_x1;
    qreal m_y1;
    qreal m_x2;
    qreal m_y2;
    listRot *rotX_samples[ROT_SAMPLES];
    listRot *rotY_samples[ROT_SAMPLES];
    listRot *rotZ_samples[ROT_SAMPLES];
    listRot *currRotX;
    listRot *currRotY;
    listRot *currRotZ;
    qreal m_average_rotX;
    qreal m_average_rotY;
    qreal m_average_rotZ;
    qreal m_calibrateMinX;
    qreal m_calibrateMinY;
    qreal m_calibrateMinZ;
    qreal m_calibrateMaxX;
    qreal m_calibrateMaxY;
    qreal m_calibrateMaxZ;
    QPen pen;

    QColor m_color;
    int m_penWidth;
    bool m_active;

private:
    bool findIntersection(qreal x11, qreal y11, qreal x12, qreal y12,
                          qreal x21, qreal y21, qreal x22, qreal y22,
                          qreal &x , qreal &y );

public slots:
    void onItemActiveChanged();
    void onReadingChanged();
    void onReadingChanged2();
    
};

#endif // HORIZON_H
